package com.dc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dc.FastdfsUtils;
import com.dc.common.ResponseResultVO;
import com.dc.constat.SystemConstant;
import com.dc.entity.InspectionPosition;
import com.dc.entity.InspectionRelation;
import com.dc.entity.QrCodeManagement;
import com.dc.entity.ro.InspectionPositionRO;
import com.dc.mapper.InspectionPositionMapper;
import com.dc.mapper.InspectionRelationMapper;
import com.dc.mapper.QrCodeManagementMapper;
import com.dc.service.InspectionPositionService;
import com.dc.util.*;
import com.dc.vo.SysConfigVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.dc.common.ResponseResultVO.checkParameterIsNotNull;
import static com.dc.common.ResponseResultVO.failResult;

@Service
public class InspectionPositionServiceImpl extends ServiceImpl<InspectionPositionMapper, InspectionPosition> implements InspectionPositionService {

    @Resource
    private InspectionPositionMapper inspectionPositionMapper;
    @Resource
    private QrCodeManagementMapper qrCodeManagementMapper;
    @Resource
    private FastdfsUtils fastdfsUtils;
    @Resource
    private InspectionRelationMapper relationMapper;
    @Resource
    private RedisUtil redisUtil;

    @Override
    public ResponseResultVO batchCreateAddressQrCode(Integer num, HttpServletResponse response) {
        if (num > 100 || num < 1) {
            return failResult("单次生成二维码最大数量为1-100");
        }
        try {
            //生成的ZIP文件名为Demo.zip
            byte[] buffer = new byte[1024];
            response.getOutputStream();
            BufferedOutputStream bos = null;
            try {
                bos = new BufferedOutputStream(response.getOutputStream());
            } catch (IOException exception) {
                log.error("打印失败");
            }
            SysConfigVO patrolPointH5Url = (SysConfigVO) (redisUtil.get(SystemConstant.REDIS_CONFIG + "patrol_point_h5_url"));
            response.reset();
//            response.setContentType("application/zip;charset=utf-8");
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment:filename=file.zip");
            ZipOutputStream out = new ZipOutputStream(bos);
            //需要同时下载的两个文件result.txt ，source.txt
            for (int i = 0; i < num; i++) {

                Long aLong = SnowflakeIdWorker.generateId();
                File file = QRCodeUtils.drawLogoQRCode(patrolPointH5Url.getConfigValue() + aLong, null, UUID.randomUUID().toString().replaceAll("-", ""));
                File newFile = new File(i + ".png");
                Files.copy(file.toPath(), newFile.toPath());
                //异步上传
                ThreadPoolUtil.execute(() -> {
                    String path = null;
                    try {
                        path = fastdfsUtils.upload(Base64DecodeMultipartFile.toMultipartFile("", newFile));
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("上传fastDFS异常");
                    }
                    QrCodeManagement qrCodeManagement = new QrCodeManagement();
                    qrCodeManagement.setId(aLong);
                    qrCodeManagement.setPath(path);
                    qrCodeManagementMapper.insert(qrCodeManagement);
                    newFile.delete();
                });
                FileInputStream fis = new FileInputStream(file);
                out.putNextEntry(new ZipEntry(file.getName()));
                int len;
                //读入需要下载的文件的内容，打包到zip文件
                while ((len = fis.read(buffer)) > 0) {
                    out.write(buffer, 0, len);
                }
                out.closeEntry();
                fis.close();
                file.delete();
            }
            out.close();
            System.out.println("生成zip成功");
        } catch (Exception exception) {

        }
        return null;
    }


    @Override
    @Transactional
    public ResponseResultVO insertInspectionPosition(InspectionPositionRO ro) {
        if (null != inspectionPositionMapper.selectOne(new QueryWrapper<InspectionPosition>().lambda().eq(InspectionPosition::getName, ro.getName()))) {
            return ResponseResultVO.failResult("点位名称重复");
        }
        InspectionPosition inspectionPosition = new InspectionPosition();
        BeanUtils.copyProperties(ro, inspectionPosition);
        inspectionPosition.setId(SnowflakeIdWorker.generateId());
        return ResponseResultVO.insertResult(inspectionPositionMapper.insert(inspectionPosition));
    }

    @Override
    public ResponseResultVO updateInspectionPosition(InspectionPositionRO ro) {
        checkParameterIsNotNull(String.valueOf(ro.getId()), "id不能为空");
        if (null != inspectionPositionMapper.selectOne(new QueryWrapper<InspectionPosition>().lambda().ne(InspectionPosition::getId, ro.getId()).eq(InspectionPosition::getName, ro.getName()))) {
            return ResponseResultVO.failResult("点位名称重复");
        }
        InspectionPosition inspectionPosition = new InspectionPosition();
        BeanUtils.copyProperties(ro, inspectionPosition);
        return ResponseResultVO.updateResult(inspectionPositionMapper.updateById(inspectionPosition));
    }

    @Override
    @Transactional
    public ResponseResultVO updateQrCode(String id) {
        InspectionPosition inspectionPosition = inspectionPositionMapper.selectById(id);
        //将原二维码状态修改为 已使用
        QrCodeManagement management = new QrCodeManagement();
        management.setId(inspectionPosition.getQrId());
        management.setStatus(1);
        qrCodeManagementMapper.updateById(management);
        //生成新的二维码并且上传fastDFS
        QrCodeManagement qrCodeManagement = new QrCodeManagement();
        qrCodeManagement.setId(SnowflakeIdWorker.generateId());
        String fileName = inspectionPosition.getName() + inspectionPosition.getAddress();
        // TODO 地址等待确认
        File file = QRCodeUtils.drawLogoQRCode("h5地址" + qrCodeManagement.getId(), fileName, fileName);
        String path = null;
        try {
            path = fastdfsUtils.upload(Base64DecodeMultipartFile.toMultipartFile(fileName + inspectionPosition.getAddress(), file));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传fastDFS异常");
        }
        qrCodeManagement.setPath(path);
        qrCodeManagementMapper.insert(qrCodeManagement);
        file.delete();
        inspectionPosition.setQrId(qrCodeManagement.getId());
        inspectionPosition.setPath(path);
        return ResponseResultVO.insertResult(inspectionPositionMapper.updateById(inspectionPosition));
    }

    @Override
    @Transactional
    public ResponseResultVO deleteInspectionPosition(String ids) {
        checkParameterIsNotNull(ids, "id不能为空");
        List<String> idList = Arrays.asList(ids.split(","));
        List<InspectionRelation> inspectionRelations = relationMapper.selectList(new QueryWrapper<InspectionRelation>().lambda().in(InspectionRelation::getPositionId, idList));
        if (CollectionUtils.isNotEmpty(inspectionRelations)) {
            InspectionPosition inspectionPosition = inspectionPositionMapper.selectById(inspectionRelations.get(0).getPositionId());
            return ResponseResultVO.failResult("点位:" + inspectionPosition.getName() + " 已经绑定路线,不允许删除!");
        }
        List<InspectionPosition> inspectionPositions = inspectionPositionMapper.selectBatchIds(idList);
        List<Long> qrCodeIds = inspectionPositions.stream().map(InspectionPosition::getQrId).collect(Collectors.toList());
        qrCodeManagementMapper.deleteBatchIds(qrCodeIds);
        //异步删除fastDFS上图片
        ThreadPoolUtil.execute(() -> {
            for (InspectionPosition path : inspectionPositions) {
                fastdfsUtils.delete(path.getPath());
            }
        });
        return ResponseResultVO.deleteResult(inspectionPositionMapper.deleteBatchIds(idList));
    }

    @Override
    public ResponseResultVO selectPositionListByPage(InspectionPositionRO ro) {
        Page page = new Page<Map<String, Object>>(ro.getCurrentPage(), ro.getPageSize());
        QueryWrapper<InspectionPosition> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(StringUtils.isNotBlank(ro.getAddress()), InspectionPosition::getAddress, ro.getAddress());
        queryWrapper.lambda().like(StringUtils.isNotBlank(ro.getName()), InspectionPosition::getName, ro.getName());
        queryWrapper.lambda().orderByDesc(InspectionPosition::getCreateTime);
        return ResponseResultVO.resultList(inspectionPositionMapper.selectPage(page, queryWrapper), ro);

    }

    @Override
    public ResponseResultVO selectInspectionPositionList() {
        QueryWrapper<InspectionPosition> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().isNull(InspectionPosition::getQrId);
        List<InspectionPosition> inspectionPositions = inspectionPositionMapper.selectList(queryWrapper);
        return ResponseResultVO.successResult(inspectionPositions);
    }

}
